#include "ficheros_basico.h"
#include "directorios.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>



//Variables globales
#define PROCESOS 100
#define LINEAS 100
#define TAM_LINEA 30

//Número de procesos acabados
int acabados = 0;


//Función encargada de recoger los procesos que están en estado Zombie.
void enterrador(){

	while(wait3(NULL, WNOHANG, NULL) > 0){	
		acabados++;
	}

	printf("Han acabado %d / %d\n", acabados, PROCESOS);

}



//Función encargada de crear para cada proceso (número proceso pasado por parámetro), un fichero
//llamado "proceso-*.dat" donde se escribirán 100 lineas de log
int proceso(int num_proceso){
	
	char nombre_fichero[TAM_LINEA];		
	memset(nombre_fichero, '\0', TAM_LINEA); 	

	char linea[TAM_LINEA];  	
	memset(linea, '\0', TAM_LINEA);		
	
	STAT st;
	int i;

	struct tm *t;
	time_t hora;

	sprintf(nombre_fichero, "/proceso-%d.dat", num_proceso); 	
		
	if(mi_creat(nombre_fichero) != -1){
		
		//Primera linea (Inicio de Log)	
		sprintf(linea, "Inicio log proceso %d \n\n", getpid());
		mi_write(nombre_fichero, linea, 0, strlen(linea));
		
		//100 lineas de Log
		for(i=0; i<LINEAS; i++){	

			//Obtenemos el tiempo y lo escribimos en el fichero, asi como el número de linea
			hora = time(NULL);
			t = localtime(&hora); 
			sprintf(linea, "%d:%d:%d Linea número %d \n", t->tm_hour, t->tm_min, t->tm_sec, i);
			
			if(mi_stat(nombre_fichero, &st) != -1){
				mi_write(nombre_fichero, linea, st.tamanyo, strlen(linea));
			}
			
			//Cada linea se genera cada 0,1 segundos.
			usleep(100000); 
		}
		
		//Última linea (Fin de Log)
		sprintf(linea, "\nFin log proceso %d \n", getpid());
		
		if(mi_stat(nombre_fichero, &st) != -1){
			mi_write(nombre_fichero, linea, st.tamanyo, strlen(linea));
		}

	}		
	
}



//Función encargada de listar el directorio raiz "/"
int listado(){

	unsigned int p_inodo_dir, p_inodo, p_entrada;
	p_inodo_dir = p_inodo = p_entrada = 0;	

	int res = buscar_entrada("/", &p_inodo_dir, &p_inodo, &p_entrada);

	if(res == -1){
		printf("NO EXISTE EL DIRECTORIO \n");

		return -1;
	}	

	unsigned char bufferdir[tam_bloq*6];
	memset(bufferdir, '\0', (tam_bloq*6));

	int k = mi_dir("/", bufferdir);

	printf("\nNúmero de entradas que hay en el directorio = %d \n", k);

	if(k > 0){
		//imprimir_directorio("/", bufferdir);
		char *camino = "/";
		int cont;
		
		printf("      ====================================\n");
		printf("     | CONTENIDO DEL DIRECTORIO: '%s'\n", camino);
		printf("      ====================================\n\n");
		printf("     NOMBRE                   \n");
		printf("    ----------------------------------------\n");
		
		
		for(cont=0; cont<(tam_bloq*6); cont++){

			if(bufferdir[cont] == ':'){
				printf("\n");
			}else{
				printf("%c", bufferdir[cont]);
			}
		}

		for(cont=0; cont<5; cont++){
		printf("\n");
	}
		
		return 1;
	}
	else{
		printf("\nEl directorio '%s' está vacio!! \n\n", "/");

		return -1;
	}


}


//Función encargada de borrar todos los procesos que se llamen "proceso-*.dat"
void borrar_procesos(){

	int i, res;	

	char nombre_fichero[TAM_LINEA];
	memset(nombre_fichero, '\0', TAM_LINEA);

	
	for(i=1; i<=PROCESOS; i++) {
		sprintf(nombre_fichero, "/proceso-%d.dat", i);

		res = mi_unlink(nombre_fichero); 

		//printf("RES = %d \n", res);

		if(res == -1){
			printf("El proceso %s no existe \n", nombre_fichero);
		}
		else{
			printf("Eliminado %s\n", nombre_fichero);
		}

		memset(nombre_fichero, '\0', TAM_LINEA);

	}

	listado();

}






//MAIN
int main (int argc, char **argv) {


	if(argc != 2){
                printf("Número de parametros incorrecto!! (Ej: ./simulacion  'Nombre del disco' ) \n\n");

		return -1;
	}
	else{

		int pid_proceso;	

		//Montamos sistema de ficheros.	
		montar(argv[1]);


		//Antes de generar los ficheros, obtenemos un listado del directorio y se 
		//borrarán todos los ficheros que se llamen "proceso-*.dat" si existen
		int cont = listado();

		//Si hay ficheros
		if(cont > 0){ 
			borrar_procesos(); 
		}
	
		signal(SIGCHLD, enterrador);
	
		int i;

		for(i=1; i<=PROCESOS; i++){
			
			if((pid_proceso = fork()) == 0){
				proceso(i);
				exit(0); 
			}

			//Si en algún momento se produce un error de creación de procesos, intentamos crearlo de nuevo.
			else if(pid_proceso < 0){ 
				i--;   
				enterrador();
			}

			//Cada proceso se genera cada 1 segundo.
			sleep(1); 
		}
		
		while(acabados<PROCESOS){
			pause(); 	
		}

		//Por último, listamos el contenido del directorio "/"
		listado();

		//Desmontamos sistema de ficheros.	
		desmontar();

	}

}